//
//  GamePlay.m
//  TheifRunning
//
//  Created by Lion on 6/12/14.
//  Copyright (c) 2014 Apportable. All rights reserved.
//

#import "GamePlay.h"

/**
 *  Import object Class
 */
#import "Theif.h"
#import "Tree.h"
#import "Tree_2.h"
#import "Rock.h"
#import "Obstacle.h"
//____________________________________________________________________________//

/**
 *  Import view Class
 */
#import "Background.h"
#import "BackgroundMountain.h"
#import "BackgroundBigTree.h"
//____________________________________________________________________________//

/**
 *  Define Value
 */

typedef NS_ENUM(NSInteger, DrawingOrder) {
    DrawingOrderTree,
    DrawingOrderTreeX,
    DrawingOrderRock,
    DrawingOrderObstacle,
    DrawingOrderGround,
    DrawingOrderTheif
};

typedef NS_ENUM(NSInteger, GameState) {
    GameStatePausing,
    GameStatePlaying
};
static const CGFloat firstObstaclePosition = 280.f;
static const CGFloat distanceBetweenObstacles = 300.f;
//____________________________________________________________________________//


@implementation GamePlay {
    BOOL canTouch;
    CCPhysicsNode *_physicsNode;
    CCPhysicsNode *_physicBg;
    CCPhysicsNode *_physicRock;
    CCNode *_viewNode;
    //view
    CCNode *_bgNode;
    CCNode *_bgBigTree;
    CCNode *_bgNodeMountain;
    Background *_thisBg;
    BackgroundMountain *_thisMountain;
    BackgroundBigTree *_thisBgBigTree;
    CCButton *_restart;
    CCButton *_backButton;
    
    //theif object
    CCNode *_theif;
    CCSprite *_theif2;
    
    //obstacle object
    NSMutableArray *obstacleArray;
    
    //ground object
    CCNode *_ground1;
    CCNode *_ground2;
    NSArray *_grounds;
    
    //big tree object
    NSMutableArray *_bigTrees;
    NSMutableArray *_bigTreesX;
    
    CCNode *_mountain;
    NSArray *_testMountains;
    
    //rock object
    NSMutableArray *_rocks;
   NSMutableArray *_rocks1;
    NSMutableArray *_rocks2;
    
    //handler time in touch
    NSDate *startTime;
    NSDate *endTime;
    
    //physicbodys theif
    float velocityDown;
    
    CCLabelTTF *_score;
    CGFloat scrollSpeed;
    CGFloat scrollSpeedBG;
    CGFloat scrollSpeedRock;
    
    int xCounter;
    int scrollCounter;
    BOOL isNotRunning;
    NSInteger gameState;
}

#pragma mark-
#pragma mark- Game Circle
- (void)didLoadFromCCB {
    [_restart setUserInteractionEnabled:NO];
    [_restart setVisible:NO];
    [_restart setZOrder:100];
    [_backButton setZOrder:100];
    [_score setZOrder:100];
    scrollCounter = 1;
    gameState = GameStatePlaying;
    CCBAnimationManager* animationManager = _theif.userObject;
    [animationManager runAnimationsForSequenceNamed:@"Running"];
    
    xCounter =0;
    isNotRunning = NO;
    canTouch = YES;
    self.userInteractionEnabled = TRUE;
    scrollSpeed = 80.f;
    scrollSpeedBG = 10.f;
    scrollSpeedRock = 200.f;

    //fixing velocity for theif
    velocityDown = 500;
    
    //adding ground array
    _grounds = @[_ground1, _ground2];
    
    //adding obstacle array
    obstacleArray = [[NSMutableArray alloc]init];
    [self spawnNewObstacle];
    [self spawnNewObstacle];
    [self spawnNewObstacle];
    [self spawnNewObstacle];
    
    for (CCNode *ground in _grounds) {
        ground.zOrder = 97;
    }

    //theif
    _theif.zOrder = 99;
    _theif.physicsBody.collisionType = @"hero";
    
    _thisBg = (Background*)[CCBReader load:@"Background"];
    _thisBg.normalTree1.physicsBody.collisionType = @"tree";
    _thisBg.zOrder = 0;
    [_bgNode setZOrder:90];
    [_bgNode addChild:_thisBg];
    
    _thisMountain = (BackgroundMountain*)[CCBReader load:@"BackgroundMountain"];
    [_bgNodeMountain setZOrder:10];
    [_bgNodeMountain addChild:_thisMountain];
    
    _thisBgBigTree = (BackgroundBigTree*)[CCBReader load:@"BackgroundBigTree"];
    [_bgBigTree setZOrder:95];
    [_bgBigTree addChild:_thisBgBigTree];
    
    [_physicsNode setZOrder:99];
    _physicsNode.collisionDelegate = self;
    
    
    //trigger pre start game
    [self schedule:@selector(preStart:) interval:1];
    
}
#pragma mark-
#pragma mark- Collision Handler
-(BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair hero:(CCNode *)hero tree:(CCNode *)nodeB {
    CCLOG(@"--> Ground");
    return TRUE;
}
-(BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair hero:(CCNode *)hero obstacle:(CCNode *)nodeB {
    CCLOG(@"--> Obstacle");
    [self gameOver];
    return YES;
}
- (void) pauseGame{
    [_theif setOpacity:0.2];
    [_restart setUserInteractionEnabled:YES];
    [_restart setVisible:YES];
}
- (void)gameOver {
    [_thisBg setPaused:YES];
    [_thisMountain setPaused:YES];
    [_thisBgBigTree setPaused:YES];
    scrollCounter = 0;
    scrollSpeed =0;
    CCActionMoveBy *moveBy = [CCActionMoveBy actionWithDuration:0.2f position:ccp(-2, 2)];
    CCActionInterval *reverseMovement = [moveBy reverse];
    CCActionSequence *shakeSequence = [CCActionSequence actionWithArray:@[moveBy, reverseMovement]];
    CCActionEaseBounce *bounce = [CCActionEaseBounce actionWithAction:shakeSequence];
    CCActionCallFunc *callback = [CCActionCallFunc actionWithTarget:self selector:@selector(pauseGame)];
    [self runAction:bounce];
    
    CCActionRotateBy *rotateBy = [CCActionRotateBy actionWithDuration:1.0f angle:-600];
    CCActionJumpBy *jumpBy = [CCActionJumpBy actionWithDuration:1.0f position:ccp(-200, 80) height:150 jumps:1];
    CCActionSpawn *spaw = [CCActionSpawn actions:rotateBy, jumpBy, nil];
    CCActionSequence *sequenceTheif = [CCActionSequence actions:spaw, callback, nil];
    [_theif runAction:sequenceTheif];
}
#pragma mark-
#pragma mark- Object Handler
#define ARC4RANDOM_MAX      0x100000000
- (void) spawnNewObstacle{
    CCNode *previousObstacle = [obstacleArray lastObject];
    CGFloat previousObstacleXPosition = previousObstacle.position.x;
    if (!previousObstacle) {
        // this is the first obstacle
        previousObstacleXPosition = firstObstaclePosition;
    }
    Obstacle *obstacle = (Obstacle*)[CCBReader load:@"Obstacle"];
    CGFloat random = ((double)arc4random() / ARC4RANDOM_MAX);
    obstacle.position = ccp(previousObstacleXPosition + distanceBetweenObstacles + (random * 1000), 79);
//    [obstacle setRandomPosition];
    [obstacle setZOrder:DrawingOrderObstacle];
    [_physicsNode addChild:obstacle];
    [obstacleArray addObject:obstacle];
}

#pragma mark-
#pragma mark- Background handler
//trigger prestart game
-(void)preStart:(CCTime)dt{
    xCounter++;
    if (xCounter == 1) {
        isNotRunning = YES;
        [self unschedule:@selector(preStart:)];
    }
}

//main thread: UI updating
- (void)update:(CCTime)delta {
    if (gameState == GameStatePausing) {
        return;
    }
    scrollSpeed += scrollCounter;
    // loop the ground
    for (CCNode *ground in _grounds) {
        // get the world position of the ground
        CGPoint groundWorldPosition = [_physicsNode convertToWorldSpace:ground.position];
        // get the screen position of the ground
        CGPoint groundScreenPosition = [self convertToNodeSpace:groundWorldPosition];
        // if the left corner is one complete width off the screen, move it to the right
        if (groundScreenPosition.x <= (-1 * ground.contentSize.width)) {
            ground.position = ccp(ground.position.x + 2 * ground.contentSize.width-15, ground.position.y);
        }
    }
    
    //handle obstacle
    NSMutableArray *offScreenObstacles = nil;
    for (CCNode *obstacle in obstacleArray) {
        CGPoint obstacleWorldPosition = [_physicsNode convertToWorldSpace:obstacle.position];
        CGPoint obstacleScreenPosition = [self convertToNodeSpace:obstacleWorldPosition];
        if (obstacleScreenPosition.x < -obstacle.contentSize.width) {
            if (!offScreenObstacles) {
                offScreenObstacles = [NSMutableArray array];
            }
            [offScreenObstacles addObject:obstacle];
        }
    }
    for (CCNode *obstacleToRemove in offScreenObstacles) {
        [obstacleToRemove removeFromParent];
        [obstacleArray removeObject:obstacleToRemove];
        // for each removed obstacle, add a new one
        [self spawnNewObstacle];
    }
    
    
    //handle theif position
    if (_theif.position.y > _ground1.contentSize.height +2) {
        canTouch = NO;
    }else{
        canTouch = YES;
    }
    if (_theif.position.y >= self.contentSize.height) {
        CGPoint theifPosition = _theif.position;
        theifPosition.y = self.contentSize.height;
        _theif.position = theifPosition;
    }
    
    // clamp velocity
    float yVelocity = clampf(_theif.physicsBody.velocity.y, -1 * MAXFLOAT, velocityDown);
    _theif.physicsBody.velocity = ccp(0, yVelocity);
    
    if (_theif.position.x < 350 && isNotRunning) {
        _theif.position = ccp(_theif.position.x + delta * scrollSpeed *2, _theif.position.y);
    }else{
        _theif.position = ccp(_theif.position.x + delta * scrollSpeed, _theif.position.y);
    }
    if(isNotRunning){
        [_score setString:[NSString stringWithFormat:@"%d", (-1*(int)_physicsNode.position.x) /10]];
    }
    _physicsNode.position = ccp(_physicsNode.position.x - (scrollSpeed *delta), _physicsNode.position.y);
}
#pragma mark-
#pragma mark- Touch Action
- (void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
    startTime = [NSDate date];
}
- (void)touchMoved:(UITouch *)touch withEvent:(UIEvent *)event{
}
- (void)touchEnded:(UITouch *)touch withEvent:(UIEvent *)event{
    endTime = [NSDate date];
    NSTimeInterval secondsBetween = [endTime timeIntervalSinceDate:startTime];
    float impulseValue = 0;
    impulseValue = 5000 * secondsBetween;
    if(impulseValue > 700)
        impulseValue = 500;
    else
        impulseValue = 350;
    velocityDown = impulseValue;
    if (canTouch) {
        /**
         *  other way to create animation for jumping
         *
         */
        //        CCActionMoveBy *move = [CCActionMoveBy actionWithDuration:0.5 position:ccp(0, 50)];
        //        [_theif runAction:move];
        //        [_theif.physicsBody applyImpulse:ccp(0, -1 * _theif.physicsBody.velocity.y)];
        [_theif.physicsBody applyImpulse:ccp(0, impulseValue)];
//        CCBAnimationManager* animationManager = _theif.userObject;
//        [animationManager runAnimationsForSequenceNamed:@"Jumping"];
//        [_theif.userObject setCompletedAnimationCallbackBlock:^(id sender){
//            [animationManager runAnimationsForSequenceNamed:@"Running"];
//        }];
        canTouch = NO;
    }
}
#pragma mark-
#pragma mark- Button Action
- (void) BackButtonDidTap{
    CCLOG(@"BackButtonDidTap");
    CCScene *gameplayScene = [CCBReader loadAsScene:@"MainScene"];
    [[CCDirector sharedDirector] replaceScene:gameplayScene];
}

- (void) RestartButtonDidTap{
    CCLOG(@"RestartButtonDidTap");
    CCScene *gameplayScene = [CCBReader loadAsScene:@"GamePlay"];
    [[CCDirector sharedDirector] replaceScene:gameplayScene];
}

@end
